﻿using System;
using System.IO;
using System.Text;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Configuration;
using System.Web.Mvc;
using Fashion.Models;
using Fashion.ViewModels;
using System.Data;
using System.Globalization;

namespace Fashion.Controllers
{
    public class PaypalController : Controller
    {
        string authToken, txToken, query;
        string strResponse;
        FashionEntities1 FashionDB = new FashionEntities1();
        //
        // GET: /Paypal/

        public ActionResult Index()
        {
            return View();
        }


        public ActionResult IPN()
        {
            //Post back to either sandbox or live
            string strSandbox = "https://www.sandbox.paypal.com/cgi-bin/webscr";
            string strLive = "https://www.paypal.com/cgi-bin/webscr";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strSandbox);

            //Set values for the request back
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            byte[] param = Request.BinaryRead(Request.ContentLength);
            string strRequest = Encoding.ASCII.GetString(param);
            strRequest += "&cmd=_notify-validate";
            req.ContentLength = strRequest.Length;

            //for proxy
            //WebProxy proxy = new WebProxy(new Uri("http://url:port#"));
            //req.Proxy = proxy;

            //Send the request to PayPal and get the response
            StreamWriter streamOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
            streamOut.Write(strRequest);
            streamOut.Close();
            StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream());
            string strResponse = streamIn.ReadToEnd();
            streamIn.Close();

            if (strResponse == "VERIFIED")
            {
                //check the payment_status is Completed
                //check that txn_id has not been previously processed
                //check that receiver_email is your Primary PayPal email
                //check that payment_amount/payment_currency are correct
                //process payment
            }
            else if (strResponse == "INVALID")
            {
                //log for manual investigation
            }
            else
            {
                //log response/ipn data for manual investigation
            }

            return View();
        }

        public ActionResult Success()
        {
            // Used parts from https://www.paypaltech.com/PDTGen/
            // Visit above URL to auto-generate PDT script

            authToken = WebConfigurationManager.AppSettings["PDTToken"];

            //read in txn token from querystring
            txToken = Request.QueryString.Get("tx");


            query = string.Format("cmd=_notify-synch&tx={0}&at={1}", txToken, authToken);

            // Create the request back
            string url = WebConfigurationManager.AppSettings["PayPalSubmitUrl"];
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);

            // Set values for the request back
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            req.ContentLength = query.Length;

            // Write the request back IPN strings
            StreamWriter stOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
            stOut.Write(query);
            stOut.Close();

            // Do the request to PayPal and get the response
            StreamReader stIn = new StreamReader(req.GetResponse().GetResponseStream());
            strResponse = stIn.ReadToEnd();
            stIn.Close();

            // sanity check

            PDTHolderViewModel pdt;
            // If response was SUCCESS, parse response string and output details
            if (strResponse.StartsWith("SUCCESS"))
            {
                pdt = PDTHolderViewModel.Parse(strResponse);
                List<Product> Cart = null;
                                
                if (Session["cart"] != null)
                {
                    Cart = (List<Product>)Session["cart"];

                    //Add to [dbo.][Orders]
                    string[] string_format = { "HH:mm:ss MMM dd, yyyy PST", "HH:mm:ss MMM. dd, yyyy PST", "HH:mm:ss MMM dd, yyyy PDT", "HH:mm:ss MMM. dd, yyyy PDT" };
                    Order orderModel = new Order();
                    orderModel.CurrentStatus = "Pending";
                    orderModel.AddressLine1 = pdt.AddressLine1;
                    orderModel.AddressLine2 = null;
                    orderModel.City = pdt.City;
                    orderModel.Country = pdt.Country;
                    orderModel.Postalcode = pdt.PostalCode;
                    DateTime outputDateTime;
                    DateTime.TryParseExact(pdt.OrderDate, string_format, new CultureInfo("en-US"), DateTimeStyles.None, out outputDateTime);
                    orderModel.OrderDate = outputDateTime.AddHours(+15.0);
                    orderModel.ShipDate = DateTime.Today.ToUniversalTime();
                    orderModel.UserID = 4; //XQ
                    orderModel.TotalPrice = pdt.GrossTotal;

                    AddToOrder(orderModel);

                    //Add to [dbo].[OrderDetails]
                    OrderDetail orderDetailModel = new OrderDetail();
                    foreach (var product in Cart)
                    {
                        //Get color id
                        var colorModel = (from color in FashionDB.Colors
                                          where color.Name == product.color
                                          select color.ColorID).FirstOrDefault();
                        //Get size id
                        var sizeModel = (from size in FashionDB.Sizes
                                         where size.Name == product.size
                                         select size.SizeID).FirstOrDefault();

                        orderDetailModel.OrderID = orderModel.OrderID;
                        orderDetailModel.ColorID = colorModel;
                        orderDetailModel.SizeID = sizeModel;
                        orderDetailModel.Quantity = product.quantity;
                        orderDetailModel.Price = product.Price;
                        orderDetailModel.CouponID = null; //XQ
                        orderDetailModel.ProductID = product.ProductID;

                        AddToOrderDetail(orderDetailModel);
                        
                    }

                    Session.Remove("cart");
                    Session["totalItems"] = 0;

                    pdt.Message = string.Format("Thank you {0} {1} [{2}] for your payment of {3} {4}!",
                    pdt.PayerFirstName, pdt.PayerLastName, pdt.PayerEmail, pdt.GrossTotal, pdt.Currency);
                }
                else
                {
                    pdt = new PDTHolderViewModel();
                    pdt.Message = "Cannot write order to database";
                }

                
            }
            else
            {
                pdt = new PDTHolderViewModel();
               pdt.Message  = "Oooops, something went wrong...";
            }
            return View(pdt);
        }

        public void AddToOrder(Order order)
        {
            FashionDB.AddToOrders(order);
            FashionDB.SaveChanges();
            
        }

        public void AddToOrderDetail(OrderDetail orderDetailModel)
        {
            FashionDB.AddToOrderDetails(orderDetailModel);
            FashionDB.SaveChanges();
        }
        
    }
}
